(*  :Title:	Supplemental Platform for Transforms  *)

(*  :Authors:	Brian Evans, James McClellan  *)

(*
    :Summary:	Plots of m-D magnitude/phase responses
		Generates of m-D pole-zero diagrams and root loci
 *)

(*  :Context:	SignalProcessing`Support`TransSupport`  *)

(*  :PackageVersion:  2.7	*)

(*
    :Copyright:	Copyright 1989-1991 by Brian L. Evans
		Georgia Tech Research Corporation

	Permission to use, copy, modify, and distribute this software
	and its documentation for any purpose and without fee is
	hereby granted, provided that the above copyright notice
	appear in all copies and that both that copyright notice and
	this permission notice appear in supporting documentation,
	and that the name of the Georgia Tech Research Corporation,
	Georgia Tech, or Georgia Institute of Technology not be used
	in advertising or publicity pertaining to distribution of the
	software without specific, written prior permission.  Georgia
	Tech makes no representations about the suitability of this
	software for any purpose.  It is provided "as is" without
	express or implied warranty.
 *)

(*  :History:	*)

(*  :Keywords:	pole-zero diagrams, frequency response  *)

(*
    :Source:	{Multidimensional Digital Signal Processing}, 1984,
		  by D. Dudgeon and R. Mersereau
 *)

(*
    :Warning:	The transform objects LTransData and ZTransData must
		be defined before this file is loaded (see "ROC.m").
 *)

(*  :Mathematica Version:  1.2 or 2.0  *)

(*  :Limitation:  *)

(*
    :Discussion:  This file has two sections:

		A.  Magnitude and phase plots (for 2-D signals)
		B.  Pole-zero diagrams and root maps (for 2-D transforms)

	These sections display the results of transform objects.
 *)

(*  :Functions:	  *)


If [ TrueQ[ $VersionNumber >= 2.0 ],
     Off[ General::spell ];
     Off[ General::spell1 ] ]


(*  B E G I N     P A C K A G E  *)

BeginPackage[ "SignalProcessing`Support`MDSupport`" ]
EndPackage[]

BeginPackage[ "SignalProcessing`Support`TransSupport`",
	      "SignalProcessing`Support`ROC`",
	      "SignalProcessing`Support`SigProc`",
	      "SignalProcessing`Support`SupCode`" ]


Begin["`Private`"]


(*  lineImpulsemDT  *)
lineImpulsemDT[transq_, t_, s_, slist_, nleft_, fun_] :=
	Block [	{dim, dimsleft, lastrminus, lastrplus, result, rminus, rplus},
		rminus = GetRMinus[t];
		rplus = GetRPlus[t];
		lastrminus = If [ ListQ[rminus], Last[rminus], rminus ];
		lastrplus  = If [ ListQ[rplus],  Last[rplus],  rplus  ];
		dimsleft = Length[nleft];
		result = SubstituteForT[transq, t, s, Apply[fun, slist]];
		For [ dim = 1, dim <= dimsleft, dim++,
		      result = ScaleT [ transq, result, SignalProcessing`ROCinfo[nleft[[dim]], lastrminus, lastrplus]] ];
		result ]

(*  multiDInvTransform  *)
multiDInvTransform[e_, s_, t_, op_, transq_, trans_, makeobject_, tdefault_] :=
	Block [	{dim, newop, numdims, result, rminus, roclist,
		 rplus, sexpr, timedims, tlist},
		numdims = Length[s];
		timedims = Length[t];
		tlist = If [ TrueQ[ numdims > timedims ],
			     Message[ MultiDInvTransform::notenough ];
			       DummyVariables[ numdims, tdefault],
			     Take[t, numdims] ]; 
		newop = multiDLookup[op, s, tlist];
		If [ transq[e],
		     rplus = GetRPlus[e];
		     rminus = GetRMinus[e];
		     result = TheFunction[e];
		     For [ dim = 1, dim <= numdims, dim++,
			   roclist = { result, rminus[[dim]], rplus[[dim]] };
			   sexpr = makeobject[ roclist, s[[dim]] ];
			   result = trans[sexpr, s[[dim]], tlist[[dim]], newop] ],
		     result = e;
		     For [ dim = 1, dim <= numdims, dim++,
			   result = trans[result, s[[dim]], tlist[[dim]], newop] ] ];
		result ]

(*  multiDLookup  *)
expandpairs[ x_, nlist_, X_, zlist_, roc_] :=
	Block [ {dim, exprx, exprX, fullrhs, i, org, pattern, rocflag, rules},
		rocflag = ! EmptyQ[roc];
		dim = Length[nlist];
		org = Apply[x,
			    Prepend[ Map[GeneratePattern, Rest[nlist]], 
				     nlist[[1]] ] ];
		rhs = Apply[X, nlist];
		rhs[[1]] = zlist[[1]];
		fullrhs = If [ rocflag, Prepend[roc[[1]], rhs], rhs ];
		rules = { org -> fullrhs };
		lhs = Apply[ X, org ];
		For [ i = 2, i <= dim, i++,
		      lhs[[i-1]] = GeneratePattern[ zlist[[i-1]] ];
		      lhs[[i]] = nlist[[i]];
		      rhs[[i]] = zlist[[i]];
		      fullrhs = If [ rocflag, Prepend[roc[[i]], rhs], rhs ];
		      AppendTo[ rules, lhs -> fullrhs ] ];
		ToCollection[rules] ]

expandone[ x_[nvars___] -> X_[zvars___], nlist_, zlist_ ] :=
	expandpairs[x, {nvars}, X, {zvars}, {}] /;
	SubsetQ[{nvars}, nlist] && SubsetQ[{zvars}, zlist]
expandone[ x_[nvars___] :> X_[zvars___], nlist_, zlist_ ] :=
	expandpairs[x, {nvars}, X, {zvars}, {}] /;
	SubsetQ[{nvars}, nlist] && SubsetQ[{zvars}, zlist]
expandone[ x_[nvars___] -> { X_[zvars___], rm_, rp_ }, nlist_, zlist_ ] :=
	expandpairs[x, {nvars}, X, {zvars}, Transpose[{rm,rp}]] /;
	SubsetQ[{nvars}, nlist] && SubsetQ[{zvars}, zlist]
expandone[ x_[nvars___] :> { X_[zvars___], rm_, rp_ }, nlist_, zlist_ ] :=
	expandpairs[x, {nvars}, X, {zvars}, Transpose[{rm,rp}]] /;
	SubsetQ[{nvars}, nlist] && SubsetQ[{zvars}, zlist]
expandone[ rule_, nlist_, zlist_ ] := rule

multiDLookup[op_, nlist_, zlist_] :=
	Block [ {lookupPairs, newop, newpairs},
		newop = op;
		lookupPairs = Replace[TransformLookup, op];
		If [ ! SameQ[lookupPairs, TransformLookup] &&
		     ! SameQ[lookupPairs, {}],
		     newpairs = Map[expandone[#, nlist, zlist]&, lookupPairs];
		     newop = Join[ RemoveOptions[op, {TransformLookup}],
				   { TransformLookup -> newpairs } ] ];
		newop ]

(*  multiDTransform  *)
multiDTransform[makeobjectfun_, transform_, transq_, e_, time_, s_, sl_, op_] :=
	Block [	{dialflag, index, newop, numdims, result, slist},
		numdims = Length[time];
		result = e;
		slist = If [ AtomQ[sl], Table[sl, {index, 1, numdims}], sl ];
		If [ Length[slist] < numdims,
		     Message[MultiDTransform::notenough];
		     slist = DummyVariables[numdims, s] ];
		newop = multiDLookup[op, time, slist];
		For [ index = 1, index <= numdims, index++,
		      result = transform [ newop, result, time[[index]],
					   slist[[index]], time, slist ];
		      If [ ! TrueQ[transq[result]], Break[] ] ];
		makeobjectfun[result] ]

multiDTransform[makeobjectfun_, transform_, transq_, e_, time_, s_, sl_] :=
	Block [	{index, numdims, result, slist},
		numdims = Length[time];
		result = e;
		slist = If [ AtomQ[sl], Table[sl, {index, 1, numdims}], sl ];
		If [ Length[slist] < numdims,
		     Message[MultiDTransform::notenough];
		     slist = DummyVariables[numdims, s] ];
		For [ index = 1, index <= numdims, index++,
		      result = transform [ result, time[[index]],
					   slist[[index]], time, slist ];
		      If [ ! TrueQ[transq[result]], Break[] ] ];
		makeobjectfun[result] ]


(*  E N D     P A C K A G E  *)

End[]
EndPackage[]


(*  E N D I N G     M E S S A G E  *)

Print["Routines supporting multidimensional transforms are loaded."]
Null
